Skip to content

Fix JsonEncode treating tables with index 0 as arrays - #454

Open
Kipstz wants to merge 2 commits into
BeamMP:minorfrom
Kipstz:fix-jsonencode-index-zero
Open

Fix JsonEncode treating tables with index 0 as arrays#454
Kipstz wants to merge 2 commits into
BeamMP:minorfrom
Kipstz:fix-jsonencode-index-zero

Conversation

@Kipstz

@Kipstz Kipstz commented Dec 24, 2025

Copy link
Copy Markdown
Contributor

Summary

  • Fix Util.JsonEncode incorrectly encoding Lua tables with index 0 as JSON arrays
  • Added IsLuaArray() helper function that validates all keys are integers >= 1
  • Tables with non-standard indices (like 0) are now correctly encoded as JSON objects

Closes #348

Before

Util.JsonEncode({[0]="a", [1]=true, [2]=0.1})
-- Output: ["a",true,0.1]  (incorrect - data loss)

After

Util.JsonEncode({[0]="a", [1]=true, [2]=0.1})
-- Output: {"0":"a","1":true,"2":0.1}  (correct)

Tables with index 0 should be encoded as JSON objects, not arrays.
Lua arrays start at index 1, so any table with keys outside 1-N range
should be treated as an object.

Added IsLuaArray() helper that checks all keys are integers >= 1.

Closes BeamMP#348
@WiserTixx

Copy link
Copy Markdown
Collaborator

The issue also mentions this related behaviour:
#348 (comment)

I'd like to add another weird behavior with tables to the ticket, with Util.JsonDecode this time:

When I run Util.JsonDecode('[1,null,3,4]') I expect to get this object : { [1] = 1, [3] = 3, [4] = 4 }

But instead I get : { [1] = 1, [2] = 3, [3] = 4 } or simplified { 1, 3, 4 }

The null 2nd index was completely omitted by the JSON parser

Would you mind attempting to fix this as well in this pr?

@Kipstz

Kipstz commented Dec 29, 2025

Copy link
Copy Markdown
Contributor Author

The issue also mentions this related behaviour: #348 (comment)

I'd like to add another weird behavior with tables to the ticket, with Util.JsonDecode this time:
When I run Util.JsonDecode('[1,null,3,4]') I expect to get this object : { [1] = 1, [3] = 3, [4] = 4 }
But instead I get : { [1] = 1, [2] = 3, [3] = 4 } or simplified { 1, 3, 4 }
The null 2nd index was completely omitted by the JSON parser

Would you mind attempting to fix this as well in this pr?

Yes, I can. I'll look at this tomorrow.

IrPgFKS0 added a commit to IrPgFKS0/BeamMP-Server that referenced this pull request Sep 7, 2026
…(shutdown hang), the

latter guarded for combined-host mode

BeamMP#454 -- Util.JsonEncode treated ANY numeric key as an array index, so a plugin
table like {[0]="a",[1]=true} encoded as the bare array ["a",true] and the 0 key
vanished silently: the array branch push_back()es values and drops keys. Zero,
negative and fractional keys all hit it. A table is now an array only when every
key is an integer >= 1 (IsLuaArray), applied at both call sites.

BeamMP#501 -- GracefullyShutdown could run every subsystem handler and then hang
forever on a lingering thread or a static destructor, leaving a server that had
"shut down" but never exited. It now _Exit(0)s once the handlers have run
(_Exit deliberately skips atexit/static destructors -- that is what makes it
immune to those hangs).

FORK GUARD on BeamMP#501: only for the STANDALONE server. In combined-host mode the
server is a library inside the launcher process, so exiting there would kill the
launcher and the host's own game session with it. Same reasoning as the existing
hard-shutdown guard a few lines above, which already checks IsEmbedded().

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Util.JsonEncode considers tables with index 0 as arrays

2 participants